package httpclient

import (
	"bytes"
	"encoding/json"
	"fmt"
	"io"
	"mcp-clarification-service/internal/tools"
	"net/http"
	"time"
)

// Client HTTP客户端
type Client struct {
	baseURL    string
	httpClient *http.Client
	timeout    time.Duration
}

// NewClient 创建新的HTTP客户端
func NewClient(baseURL string, timeout time.Duration) *Client {
	return &Client{
		baseURL: baseURL,
		httpClient: &http.Client{
			Timeout: timeout,
		},
		timeout: timeout,
	}
}

// AskQuestionsRequest 请求结构
type AskQuestionsRequest struct {
	Questions []tools.Question `json:"questions"`
	Timeout   int              `json:"timeout"`
}

// AskQuestionsResponse 响应结构
type AskQuestionsResponse struct {
	Answers   []tools.Answer `json:"answers"`
	Cancelled bool           `json:"cancelled"`
	Error     string         `json:"error,omitempty"`
}

// AskQuestions 发送批量提问请求
func (c *Client) AskQuestions(questions []tools.Question, timeout int) (*AskQuestionsResponse, error) {
	req := AskQuestionsRequest{
		Questions: questions,
		Timeout:   timeout,
	}

	data, err := json.Marshal(req)
	if err != nil {
		return nil, fmt.Errorf("failed to marshal request: %w", err)
	}

	resp, err := c.httpClient.Post(c.baseURL+"/ask", "application/json", bytes.NewReader(data))
	if err != nil {
		return nil, fmt.Errorf("failed to send request: %w", err)
	}
	defer resp.Body.Close()

	if resp.StatusCode == http.StatusConflict {
		return nil, fmt.Errorf("another request is in progress")
	}

	if resp.StatusCode != http.StatusOK {
		body, _ := io.ReadAll(resp.Body)
		return nil, fmt.Errorf("unexpected status code %d: %s", resp.StatusCode, string(body))
	}

	var result AskQuestionsResponse
	if err := json.NewDecoder(resp.Body).Decode(&result); err != nil {
		return nil, fmt.Errorf("failed to decode response: %w", err)
	}

	if result.Error != "" {
		return nil, fmt.Errorf("GUI error: %s", result.Error)
	}

	return &result, nil
}

// HealthCheck 健康检查
func (c *Client) HealthCheck() error {
	resp, err := c.httpClient.Get(c.baseURL + "/health")
	if err != nil {
		return fmt.Errorf("health check failed: %w", err)
	}
	defer resp.Body.Close()

	if resp.StatusCode != http.StatusOK {
		return fmt.Errorf("health check returned status %d", resp.StatusCode)
	}

	return nil
}
